﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.Common;
using System.Data.OracleClient;

namespace TerminologiaSinacorSrv
{
    public class AcessoDados
    {
        #region | Enumeradores |
        
        /// <summary>
        /// Campos possíveis para filtro na pesquisa de Termos Fontes
        /// </summary>
        public enum CampoFiltroTermoFonte
        {
            NOME_TERMO,
            TXT_AJUDA,
            DESC_TERMO,
            TXT_COMENTARIO,
            NOME_TERMO_SUGERIDO,
            DATA_SUGESTAO,
            NOME_RESPONSAVEL
        }

        /// <summary>
        /// Campos possíveis para filtro na pesquisa de Termos de Glossário
        /// </summary>
        public enum CampoFiltroTermoGlossario
        {
            NOME_TERMO_GLOSSARIO,
            NOME_TERMO_PRETERIDO_1,
            NOME_TERMO_PRETERIDO_2,
            NOME_TERMO_PRETERIDO_3,
            NOME_TERMO_PRETERIDO_4,
            NOME_TERMO_PRETERIDO_5,
            NOME_TERMO_PRETERIDO_6,
            DESC_TERMO_GLOSSARIO,
            NOME_ABREVIATURA_1,
            NOME_ABREVIATURA_2,
            NOME_FISICO,
            NOME_TERMO_RECOMENDADO,
            DATA_DOCUMENTACAO,
            NOME_RESPONSAVEL_DOCUMENTACAO,
            DATA_VALIDACAO,
            NOME_RESPONSAVEL_VALIDACAO,
            COMENTARIO
        }

        /// <summary>
        /// Tipos possíveis de pesquisa para Termos de Glossário
        /// </summary>
        public enum TipoPesquisaTermoGlossario
        {
            PalavraChave,
            PalavraChaveDescricao
        }

        #endregion

        #region | Construtores e Destrutores |
        
        /// <summary>
        /// Construtor padrão
        /// </summary>
        public AcessoDados()
        {
            //...
        }

        /// <summary>
        /// Destrutor
        /// </summary>
        ~AcessoDados()
        {
            //...
        }

        #endregion

        #region | Metodos Privados |
        /// <summary>
        /// Método que cria o OracleDataReader com base na query passada como parâmetro
        /// </summary>
        /// <param name="querySQL">Query a ser executada</param>
        /// <returns>Objeto OracleDataReader com dados solicitados</returns>
        private static OracleDataReader AlimentaDataReader(string querySQL)
        {
            //Se não passou a query,então sai
            if (querySQL.Replace(" ", "").Length <= 0) { return null; }

            OracleDataReader dtReaderOracle = null ;
            OracleConnection conexaoOracle = new OracleConnection();
            OracleCommand comandoOracle = new OracleCommand();

            try
            {
                //Define a string de conexão para o servidor de Desenvolvimento
                conexaoOracle.ConnectionString = @"Data Source=DES;User Id=corrmais;Password=corrwin;Integrated Security=no;";

                //Abrindo a conexao com o Oracle
                conexaoOracle.Open();

                //Define a conexão do comando
                comandoOracle.Connection = conexaoOracle;

                //Define o tipo de comando a executar
                comandoOracle.CommandType = CommandType.Text;

                //Define o comando
                comandoOracle.CommandText = querySQL;

                //Executa o comando jogando no DataReader
                dtReaderOracle = comandoOracle.ExecuteReader();
            }
            catch (Exception ex)
            {
                //Lança a exceção de volta
                throw new Exception("Erro: " + ex.Message.ToString());
            }
            finally
            {
                //Libera os recursos
                if (comandoOracle != null) { comandoOracle.Dispose(); }
                if (conexaoOracle.State != ConnectionState.Closed) { conexaoOracle.Close(); }
            }

            //Retorna o DataReader
            return dtReaderOracle;
        }

        #endregion

        #region | Metodos Publicos |
        /// <summary>
        /// Lista os Módulos existentes 
        /// </summary>
        /// <returns>Objeto OracleDataReader</returns>
        public static OracleDataReader ListaModulo()
        {
            StringBuilder querySQL = new StringBuilder();
            OracleDataReader drOracleLocal = null;

            querySQL.Append("SELECT t1.COD_MODULO, t1.NOME_MODULO, t2.COD_MODULO AS COD_MODULO_PAI, t2.NOME_MODULO AS NOME_MODULO_PAI ");
            querySQL.Append("FROM Ts_Modulo t1 LEFT JOIN Ts_Modulo t2 ON t1.COD_MODULO_PAI = t2.COD_MODULO ORDER BY t1.NOME_MODULO");
            
            try
            {
                //Manda alimentar o DataReader
                drOracleLocal = AlimentaDataReader(querySQL.ToString());
            }
            catch (Exception ex)
            {
                //Lança a exceção de volta
                throw new Exception("Erro ao tentar carregar os dados dos Módulos/Módulos-Pai!\n" + ex.Message.ToString());
            }
            
            //Retorna o DataReader
            return drOracleLocal;
            
        }

        /// <summary>
        /// Lista os Tipos de Fontes
        /// </summary>
        /// <param name="codModulo">Código do Módulo a ser filtrado</param>
        /// <returns>Objeto OracleDataReader</returns>
        public static OracleDataReader ListaTipoFonte(int? codModulo)
        {
            StringBuilder querySQL = new StringBuilder();
            OracleDataReader drOracleLocal = null;

            querySQL.Append("SELECT TS_FONTE.COD_FONTE, TS_TIPO_FONTE.NOME_TIPO_FONTE, TS_FONTE.NOME_FONTE ");
            querySQL.Append("FROM TS_TIPO_FONTE INNER JOIN TS_FONTE ON TS_TIPO_FONTE.COD_TIPO_FONTE = TS_FONTE.COD_TIPO_FONTE ");
            querySQL.Append("WHERE TS_FONTE.COD_MODULO = " + codModulo.ToString());
            
            try
            {
                //Manda alimentar o DataReader
                drOracleLocal = AlimentaDataReader(querySQL.ToString());
            }
            catch (Exception ex)
            {
                //Lança a exceção de volta
                throw new Exception("Erro ao tentar carregar os dados das Fontes!\n" + ex.Message.ToString());
            }
            
            //Retorna o DataReader
            return drOracleLocal;
        }

        /// <summary>
        /// Lista os Termos com base na Fonte
        /// </summary>
        /// <param name="codFonte">Código da Fonte a ser filtrada</param>
        /// <returns>Objeto OracleDataReader</returns>
        public static OracleDataReader ListaTermo(int? codFonte)
        {
            StringBuilder querySQL = new StringBuilder();
            OracleDataReader drOracleLocal = null;

            querySQL.Append("SELECT * FROM TS2_TERMO ");
            querySQL.Append("WHERE COD_FONTE = " + codFonte.ToString()); 
            
            try
            {
                //Manda alimentar o DataReader
                drOracleLocal = AlimentaDataReader(querySQL.ToString());
            }
            catch (Exception ex)
            {
                //Lança a exceção de volta
                throw new Exception("Erro ao tentar carregar os Termos!\n" + ex.Message.ToString());
            }
            
            //Retorna o DataReader
            return drOracleLocal;
        }

        /// <summary>
        /// Lista os Termos, mas com base na Fonte e no Termo
        /// </summary>
        /// <param name="codFonte"></param>
        /// <param name="codTermo"></param>
        /// <returns></returns>
        public static OracleDataReader ListaFiltroTermo(int? codFonte)
        {
            StringBuilder querySQL = new StringBuilder();
            OracleDataReader drOracleLocal = null;
            
            querySQL.Append("SELECT DISTINCT TXT_COMENTARIO FROM TS2_TERMO ");
            querySQL.Append("WHERE COD_FONTE = " + codFonte.ToString() + " ");
            querySQL.Append("ORDER BY TXT_COMENTARIO "); 
            
            try
            {
                //Manda alimentar o DataReader
                drOracleLocal = AlimentaDataReader(querySQL.ToString());
            }
            catch (Exception ex)
            {
                //Lança a exceção de volta
                throw new Exception("Erro ao tentar carregar os Termos!\n" + ex.Message.ToString());
            }
            
            //Retorna o DataReader
            return drOracleLocal;
            
        }

        /// <summary>
        /// Lista os Termos com base no Comentário de Filtro
        /// </summary>
        /// <param name="textoFiltro">Comentário de Filtro para pesquisa</param>
        /// <returns>Objeto OracleDataReader</returns>
        public static OracleDataReader ListaTermo(string textoFiltro)
        {
            StringBuilder querySQL = new StringBuilder();
            OracleDataReader drOracleLocal = null;

            querySQL.Append("SELECT COD_TERMO, NOME_TERMO, NOME_TERMO_SUGERIDO, COD_FONTE, TXT_COMENTARIO FROM TS2_TERMO ");
            if (textoFiltro.Replace(" ","").Length > 0) { querySQL.Append("WHERE TXT_COMENTARIO = '" + textoFiltro + "'"); }

            try
            {
                //Manda alimentar o DataReader
                drOracleLocal = AlimentaDataReader(querySQL.ToString());
            }
            catch (Exception ex)
            {
                //Lança a exceção de volta
                throw new Exception("Erro ao tentar carregar os Termos!\n" + ex.Message.ToString());
            }
            
            //Retorna o DataReader
            return drOracleLocal;
            
        }

        /// <summary>
        /// Lista os Termos com base no Filtro de Palavra-Chave
        /// </summary>
        /// <param name="palavraChave">Palavra-Chave de filtro para pesquisa</param>
        /// <param name="mascara">Caracter que serve como máscara para o filtro</param>
        /// <returns>Objeto OracleDataReader</returns>
        public static OracleDataReader ListaTermo(string palavraChave, string mascara)
        {
            StringBuilder querySQL = new StringBuilder();
            OracleDataReader drOracleLocal = null;

            //Testa a máscara. Se não veio, passo "*"
            if (mascara == string.Empty || mascara.Trim().Length == 0) { mascara = "*"; }

            querySQL.Append("SELECT DISTINCT ");
            querySQL.Append("TS2_TERMO.COD_TERMO, TS2_TERMO.NOME_TERMO, TS_MODULO.NOME_MODULO, ");
            querySQL.Append("TS_MODULO_1.NOME_MODULO AS NOME_MODULO_PAI, TS2_TERMO.TXT_COMENTARIO, ");
            querySQL.Append("TS_TIPO_FONTE.NOME_TIPO_FONTE, TS_FONTE.NOME_FONTE ");
            querySQL.Append("FROM TS_TIPO_FONTE INNER JOIN ((TS_MODULO LEFT JOIN TS_MODULO TS_MODULO_1 ");
            querySQL.Append("ON TS_MODULO.COD_MODULO_PAI = TS_MODULO_1.COD_MODULO) ");
            querySQL.Append("INNER JOIN (TS_FONTE INNER JOIN TS2_TERMO ");
            querySQL.Append("ON TS_FONTE.COD_FONTE = TS2_TERMO.COD_FONTE) ");
            querySQL.Append("ON (TS_MODULO.COD_MODULO = TS_FONTE.COD_MODULO) ");
            querySQL.Append("AND (TS_MODULO.COD_MODULO = TS_FONTE.COD_MODULO)) ");
            querySQL.Append("ON TS_TIPO_FONTE.COD_TIPO_FONTE = TS_FONTE.COD_TIPO_FONTE ");
            querySQL.Append("WHERE UPPER(TS2_TERMO.NOME_TERMO) LIKE '" + palavraChave.Replace(mascara, "%").ToUpper() + "' ");
            querySQL.Append("ORDER BY TS2_TERMO.NOME_TERMO ");

            try
            {
                //Manda alimentar o DataReader
                drOracleLocal = AlimentaDataReader(querySQL.ToString());
            }
            catch (Exception ex)
            {
                //Lança a exceção de volta
                throw new Exception("Erro ao tentar carregar os Termos por Palavra-Chave!\n" + ex.Message.ToString());
            }

            //Retorna o DataReader
            return drOracleLocal;

        }

        /// <summary>
        /// Lista os Responsáveis
        /// </summary>
        /// <returns>Objeto OracleDataReader</returns>
        public static OracleDataReader ListaResponsavel()
        {
            StringBuilder querySQL = new StringBuilder();
            OracleDataReader drOracleLocal = null;
            
            querySQL.Append("SELECT COD_RESPONSAVEL, NOME_RESPONSAVEL FROM TS_RESPONSAVEL");
            
            try
            {
                //Manda alimentar o DataReader
                drOracleLocal = AlimentaDataReader(querySQL.ToString());
            }
            catch (Exception ex)
            {
                //Lança a exceção de volta
                throw new Exception("Erro ao tentar carregar os Responsáveis!\n" + ex.Message.ToString());
            }
            
            //Retorna o DataReader
            return drOracleLocal;
            
        }

        /// <summary>
        /// Lista os Termos do Glossário
        /// </summary>
        /// <returns>Objeto OracleDataReader</returns>
        public static OracleDataReader ListaGlossario()
        {
            StringBuilder querySQL = new StringBuilder();
            OracleDataReader drOracleLocal = null;

            querySQL.Append("SELECT * FROM TS2_TERMO_GLOSSARIO");

            try
            {
                //Manda alimentar o DataReader
                drOracleLocal = AlimentaDataReader(querySQL.ToString());
            }
            catch (Exception ex)
            {
                //Lança a exceção de volta
                throw new Exception("Erro ao tentar carregar os Termos do Glossário!\n" + ex.Message.ToString());
            }
            
            //Retorna o DataReader
            return drOracleLocal;
            
        }

        /// <summary>
        /// Lista os Termos do Glossário por Palavra-Chave
        /// </summary>
        /// <param name="palavraChave">Palavra-Chave a pesquisar nos Termos do Glossário</param>
        /// <returns>Objeto OracleDataReader</returns>
        public static OracleDataReader ListaGlossario(string palavraChave)
        {
            StringBuilder querySQL = new StringBuilder();
            OracleDataReader drOracleLocal = null;

            querySQL.Append("SELECT * FROM TS2_TERMO_GLOSSARIO WHERE UPPER(NOME_TERMO_GLOSSARIO) LIKE '" + palavraChave.Replace("*","%").ToUpper() + "'");

            try
            {
                //Manda alimentar o DataReader
                drOracleLocal = AlimentaDataReader(querySQL.ToString());
            }
            catch (Exception ex)
            {
                //Lança a exceção de volta
                throw new Exception("Erro ao tentar carregar os Termos do Glossário por Palavra-Chave!\n" + ex.Message.ToString());
            }

            //Retorna o DataReader
            return drOracleLocal;

        }

        /// <summary>
        /// Lista os Termos do Glossário por Palavra-Chave ou por Palavra-Chave na Descrição
        /// </summary>
        /// <param name="tipoPesquisa">Tipo da Pesquisa a fazer</param>
        /// <param name="valorFiltro">Valor a ser pesquisado</param>
        /// <returns>Objeto OracleDataReader</returns>
        public static OracleDataReader ListaGlossario(TipoPesquisaTermoGlossario tipoPesquisa,string valorFiltro)
        {
            StringBuilder querySQL = new StringBuilder();
            OracleDataReader drOracleLocal = null;
            string campo = string.Empty;

            //Define o nome certo do campona tabela
            switch (tipoPesquisa)
            {
                case TipoPesquisaTermoGlossario.PalavraChave: campo = "NOME_TERMO_GLOSSARIO"; break;
                case TipoPesquisaTermoGlossario.PalavraChaveDescricao: campo = "DESC_TERMO_GLOSSARIO"; break;
            }

            //Monta a query
            querySQL.Append("SELECT DISTINCT COD_TERMO_GLOSSARIO, NOME_TERMO_GLOSSARIO, ");
            querySQL.Append("NOME_ABREVIATURA_1, NOME_ABREVIATURA_2, ");
            querySQL.Append("DESC_TERMO_GLOSSARIO, 'NÃO' AS IND_PREFERIDO, ");
            querySQL.Append("DECODE(IND_SINONIMO,0,'SIM','NÃO') AS IND_RECOMENDADO ");
            querySQL.Append("FROM TS2_TERMO_GLOSSARIO ");
            querySQL.Append("WHERE UPPER(" + campo + ") LIKE '" + valorFiltro.Replace("*", "%").ToUpper() + "'");
            querySQL.Append("ORDER BY NOME_TERMO_GLOSSARIO ");
            
            try
            {
                //Manda alimentar o DataReader
                drOracleLocal = AlimentaDataReader(querySQL.ToString());
            }
            catch (Exception ex)
            {
                //Lança a exceção de volta
                throw new Exception("Erro ao tentar carregar os Termos do Glossário!\n" + ex.Message.ToString());
            }

            //Retorna o DataReader
            return drOracleLocal;

        }

        /// <summary>
        /// Pesquisa dos Termos Fontes por campo focado.
        /// </summary>
        /// <param name="campoFiltro">Nome do Campo a filtrar</param>
        /// <param name="valorFiltro">Filtro informado</param>
        /// <returns>Objeto OracleDataReader</returns>
        public static OracleDataReader PesquisaTermoFonte(CampoFiltroTermoFonte campoFiltro, string valorFiltro)
        {
            StringBuilder querySQL = new StringBuilder();
            OracleDataReader drOracleLocal = null;

            //Se um dos parâmetros for NULL, então sai
            if (valorFiltro == string.Empty || valorFiltro.Replace(" ", "").Length == 0) { return null; }

            //Se foi o campo de data, então arruma o filtro
            if (campoFiltro == CampoFiltroTermoFonte.DATA_SUGESTAO)
            {
                if (valorFiltro.IndexOf("*") > -1)
                {
                    if (valorFiltro.IndexOf("*") == 0)
                    {
                        valorFiltro = " <= '" + DateTime.Parse(valorFiltro.Replace("*", "")).ToString("yyyy-mm-dd") + "'";
                    }
                    else
                    {
                        valorFiltro = " >= '" + DateTime.Parse(valorFiltro.Replace("*", "")).ToString("yyyy-mm-dd") + "'";
                    }
                }
                else
                {
                    valorFiltro = " = '" + DateTime.Parse(valorFiltro.Replace("*", "")).ToString("yyyy-mm-dd") + "'";
                }
            }
            else
            {
                valorFiltro = "LIKE '" + valorFiltro.Replace("*", "%") + "'";
            }
            
            querySQL.Append("SELECT  T1.*, T2.NOME_RESPONSAVEL ");
            querySQL.Append("FROM TS2_TERMO T1 LEFT JOIN TS_RESPONSAVEL T2 ");
            querySQL.Append("ON T1.COD_RESP_SUGESTAO = T2.COD_RESPONSAVEL ");
            querySQL.Append("WHERE " + Enum.GetName(typeof(CampoFiltroTermoFonte),campoFiltro) + " ");
            querySQL.Append(valorFiltro); 

            try
            {
                //Manda alimentar o DataReader
                drOracleLocal = AlimentaDataReader(querySQL.ToString());
            }
            catch (Exception ex)
            {
                //Lança a exceção de volta
                throw new Exception("Erro ao tentar carregar os Termos Fontes!\n" + ex.Message.ToString());
            }
            
            //Retorna o DataReader
            return drOracleLocal;
        }

        /// <summary>
        /// Pesquisa dos Termos de Glossário por campo focado.
        /// </summary>
        /// <param name="campoFiltro">Nome do Campo a filtrar</param>
        /// <param name="valorFiltro">Filtro informado</param>
        /// <returns>Objeto OracleDataReader</returns>
        public static OracleDataReader PesquisaTermoGlossario(CampoFiltroTermoGlossario campoFiltro, string valorFiltro)
        {
            StringBuilder querySQL = new StringBuilder();
            OracleDataReader drOracleLocal = null;

            //Se foi o campo de data, então arruma o filtro
            if (campoFiltro == CampoFiltroTermoGlossario.DATA_DOCUMENTACAO || campoFiltro == CampoFiltroTermoGlossario.DATA_VALIDACAO)
            {
                if (valorFiltro.IndexOf("*") > -1)
                {
                    if (valorFiltro.IndexOf("*") == 0)
                    {
                        valorFiltro = " <= '" + DateTime.Parse(valorFiltro.Replace("*", "")).ToString("yyyy-mm-dd") + "'";
                    }
                    else
                    {
                        valorFiltro = " >= '" + DateTime.Parse(valorFiltro.Replace("*", "")).ToString("yyyy-mm-dd") + "'";
                    }
                }
                else
                {
                    valorFiltro = " = '" + DateTime.Parse(valorFiltro.Replace("*", "")).ToString("yyyy-mm-dd") + "'";
                }
            }
            else
            {
                valorFiltro = "LIKE '" + valorFiltro.Replace("*", "%") + "'";
            }

            querySQL.Append("SELECT T1.*, T2.NOME_TERMO_GLOSSARIO AS NOME_TERMO_RECOMENDADO, ");
            querySQL.Append("T3.NOME_RESPONSAVEL AS NOME_RESP_DOCUMENTACAO, T4.NOME_RESPONSAVEL AS NOME_RESP_VALIDACAO ");
            querySQL.Append("FROM TS2_TERMO_GLOSSARIO T1, TS2_TERMO_GLOSSARIO T2, TS_RESPONSAVEL T3, TS_RESPONSAVEL T4 ");
            querySQL.Append("WHERE T1.COD_TERMO_RECOMENDADO = T2.COD_TERMO_GLOSSARIO ");
            querySQL.Append("AND T1.COD_RESP_DOCUMENTACAO = T3.COD_RESPONSAVEL ");
            querySQL.Append("AND T1.COD_RESP_VALIDACAO = T4.COD_RESPONSAVEL ");
            querySQL.Append("AND " + Enum.GetName(typeof(CampoFiltroTermoGlossario), campoFiltro) + " ");
            querySQL.Append(valorFiltro);

            try
            {
                //Manda alimentar o DataReader
                drOracleLocal = AlimentaDataReader(querySQL.ToString());
            }
            catch (Exception ex)
            {
                //Lança a exceção de volta
                throw new Exception("Erro ao tentar carregar os Termos de Glossário!\n" + ex.Message.ToString());
            }

            //Retorna o DataReader
            return drOracleLocal;
        }

        #endregion
    }
}
